home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsattach / RCS / fsattach.c,v < prev    next >
Encoding:
Text File  |  1992-06-20  |  33.7 KB  |  1,464 lines

  1. head     1.10;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.10
  10. date     91.01.12.16.48.11;  author jhh;  state Exp;
  11. branches ;
  12. next     1.9;
  13.  
  14. 1.9
  15. date     90.02.16.17.32.39;  author brent;  state Exp;
  16. branches ;
  17. next     1.8;
  18.  
  19. 1.8
  20. date     90.02.14.13.59.57;  author jhh;  state Exp;
  21. branches ;
  22. next     1.7;
  23.  
  24. 1.7
  25. date     89.11.29.16.19.47;  author ouster;  state Exp;
  26. branches ;
  27. next     1.6;
  28.  
  29. 1.6
  30. date     89.11.29.16.16.53;  author ouster;  state Exp;
  31. branches ;
  32. next     1.5;
  33.  
  34. 1.5
  35. date     89.10.25.18.06.42;  author jhh;  state Exp;
  36. branches ;
  37. next     1.4;
  38.  
  39. 1.4
  40. date     89.06.19.14.21.22;  author jhh;  state Exp;
  41. branches ;
  42. next     1.3;
  43.  
  44. 1.3
  45. date     89.06.07.22.14.31;  author jhh;  state Exp;
  46. branches ;
  47. next     1.2;
  48.  
  49. 1.2
  50. date     89.04.10.11.12.22;  author jhh;  state Exp;
  51. branches ;
  52. next     1.1;
  53.  
  54. 1.1
  55. date     89.03.06.12.58.45;  author jhh;  state Exp;
  56. branches ;
  57. next     ;
  58.  
  59.  
  60. desc
  61. @@
  62.  
  63.  
  64. 1.10
  65. log
  66. @new boot sequence
  67. @
  68. text
  69. @/* 
  70.  * fsattach.c --
  71.  *
  72.  *    Boot-time program to attach all disks to a server.  This
  73.  *    uses a mount file that indicates what prefixes/disks to
  74.  *    attach.  This also siphons off some availability/reliability
  75.  *    information that is put in the summary information sector
  76.  *    on each disk.
  77.  *
  78.  * Copyright 1988 Regents of the University of California
  79.  * Permission to use, copy, modify, and distribute this
  80.  * software and its documentation for any purpose and without
  81.  * fee is hereby granted, provided that the above copyright
  82.  * notice appear in all copies.  The University of California
  83.  * makes no representations about the suitability of this
  84.  * software for any purpose.  It is provided "as is" without
  85.  * express or implied warranty.
  86.  */
  87.  
  88. #ifndef lint
  89. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.9 90/02/16 17:32:39 brent Exp $ SPRITE (Berkeley)";
  90. #endif not lint
  91.  
  92. #include "fsattach.h"
  93.  
  94. char *mountFile = "mount";
  95. char *devDir = "/dev/";
  96. char *fscheck = "fscheck";
  97. int verboseLevel = -1;
  98. Boolean nomount = FALSE;
  99. Boolean sequential = FALSE;
  100. Boolean printOnly = FALSE;
  101. Boolean writeDisk = TRUE;
  102. Boolean fastboot = FALSE;
  103. Boolean debug = FALSE;
  104. int    spriteID = 0;
  105. int    maxChildren = -1;
  106. Boolean condCheck = FALSE;
  107.  
  108. Option optionArray[] = {
  109.     {OPT_STRING,   "d", (char *) &devDir,
  110.     "Device directory."},
  111.     {OPT_STRING,   "fscheck", (char *) &fscheck,
  112.     "fscheck program."},
  113.     {OPT_TRUE,   "f", (char *) &fastboot,
  114.     "Don't check disks."},
  115.     {OPT_INT,   "i", (char *) &spriteID,
  116.     "Preload prefix table with ourself as server of prefixes we export"},
  117.     {OPT_INT,   "j", (char *) &maxChildren,
  118.     "Maximum number of fscheck jobs to run at a time"},
  119.     {OPT_TRUE,   "k", (char *) &debug,
  120.     "Print debugging output."},
  121.     {OPT_STRING,   "m", (char *) &mountFile,
  122.     "File containing disk<=>prefix information."},
  123.     {OPT_TRUE,   "n", (char *) &nomount,
  124.     "No mount."},
  125.     {OPT_TRUE,   "p", (char *) &printOnly,
  126.     "Don't do anything. Just print out actions."},
  127.     {OPT_TRUE,   "s", (char *) &sequential,
  128.     "Ignore group information and run fscheck sequentially."},
  129.     {OPT_TRUE,   "v", (char *) &verbose,
  130.     "Verbose output from fsattach and fscheck."},
  131.     {OPT_FALSE,   "W", (char *) &writeDisk,
  132.     "Don't let fscheck write to the disks."},
  133.     {OPT_TRUE, "c", (char *) &condCheck,
  134.     "Conditionally check the disks (don't re-check)."},
  135.  
  136. };
  137. int numOptions = Opt_Number(optionArray);
  138.  
  139. char        *progName;
  140. int        returnCode;
  141.  
  142. int         mountTableSize = 30;
  143. int        mountTableSizeIncrement = 5;
  144. MountInfo    *mountTable;
  145. int        groupInfoSize = 10;
  146. int        groupInfoSizeIncrement = 2;
  147. GroupInfo    *groupInfo;
  148. int        numGroups;
  149. char        *tempOutputFile = ".fscheck.out";
  150. int        tempOutputFileSize = 8192;
  151. char        *heapLimitString = "1000000";
  152. Boolean        verbose = FALSE;
  153. Boolean     reboot = FALSE;
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  *----------------------------------------------------------------------
  160.  *
  161.  * main --
  162.  *
  163.  *    Main program for "fsattach":  attach disks at boottime.
  164.  *
  165.  * Results:
  166.  *    None.
  167.  *
  168.  * Side effects:
  169.  *    None.
  170.  *
  171.  *----------------------------------------------------------------------
  172.  */
  173.  
  174. main(argc, argv)
  175.     int argc;
  176.     char *argv[];
  177. {
  178.     int         mountCount = 0;
  179.     int         i;
  180.     int         j;
  181.     ReturnStatus    status;
  182.     int            numChecks;
  183.  
  184.     argc = Opt_Parse(argc, argv, optionArray, numOptions, 0);
  185.  
  186.     returnCode = OK;
  187.     progName = argv[0];
  188.     Alloc(mountTable, MountInfo, mountTableSize, "mountTable");
  189.     assert(mountTable != NULL);
  190.     for (i = 0; i < mountTableSize; i++) {
  191.     mountTable[i].status = CHILD_OK;
  192.     }
  193.     Alloc(groupInfo, GroupInfo, groupInfoSize, "groupInfo");
  194.     assert(groupInfo != NULL);
  195.     bzero(groupInfo, sizeof(GroupInfo) * groupInfoSize);
  196.     strcpy(groupInfo[0].name, "root");
  197.     numGroups = 1;
  198.     status = ParseMount(mountFile, &mountCount);
  199.     if (status != SUCCESS) {
  200.     exit(HARDERROR);
  201.     }
  202.     if (spriteID != 0) {
  203.     PreloadPrefixTable(spriteID, mountCount);
  204.     }
  205.     /*
  206.      * We don't want to check the same partition twice. If two entries in
  207.      * the parse table have the same source then set doCheck on one to
  208.      * false. Also count how many partitions have to be done in each pass.
  209.      */
  210.     numChecks = 0;
  211.     for (i = 0; i < mountCount; i++) {
  212.     for (j = i+1; j < mountCount; j++) {
  213.         if (!strcmp(mountTable[i].source, mountTable[j].source)) {
  214.         mountTable[j].doCheck = FALSE;
  215.         }
  216.     }
  217.     if (mountTable[i].doCheck == TRUE) {
  218.         numChecks++;
  219.     }
  220.     }
  221.     if (!fastboot) {
  222.     CacheWriteBack(FALSE);
  223.     CheckDisks(mountCount, numChecks);
  224.     if (!reboot) {
  225.         CacheWriteBack(TRUE);
  226.     }
  227.     }
  228.     if (reboot) {
  229.     exit(REBOOT);
  230.     }
  231.     if (!nomount) {
  232.     Prefix(mountCount);
  233.     }
  234.     MoveOutput(mountCount);
  235.  
  236.     if (debug) {
  237.     printf("(1) Exiting with %d.\n", returnCode);
  238.     }
  239.     (void) exit(returnCode);
  240. }
  241.  
  242. /*
  243.  *----------------------------------------------------------------------
  244.  *
  245.  * CheckDisks --
  246.  *
  247.  *    Check the disks. For each pass fork of an fscheck process for
  248.  *    each partition to be checked.
  249.  *
  250.  * Results:
  251.  *    FAILURE if an error occurred, SUCCESS otherwise.
  252.  *
  253.  * Side effects:
  254.  *    MountTable entries are modified.
  255.  *
  256.  *----------------------------------------------------------------------
  257.  */
  258.  
  259. ReturnStatus
  260. CheckDisks(mountCount, numChecks)
  261.     int            mountCount;    /* # entries in mount table */
  262.     int            numChecks;    /* # of partitions to check */
  263. {
  264.     int            i;
  265.     ChildInfo        *childInfo;
  266.     int            pass;
  267.     int            doneChildren;
  268.     int            activeChildren;
  269.     union wait         waitStatus;
  270.     ReturnStatus    status;
  271.     int            childPid;
  272.     MountInfo        *mountPtr;
  273.  
  274.     Alloc(childInfo, ChildInfo, numChecks, "childInfo");
  275.     assert(childInfo != NULL);
  276.     for (i = 0; i < numChecks; i++) {
  277.     childInfo[i].pid = -1;
  278.     }
  279.     activeChildren = 0;
  280.     doneChildren = 0;
  281.     if (maxChildren < 0) {
  282.     maxChildren = numGroups;
  283.     }
  284.     while (doneChildren < numChecks) {
  285.     while (activeChildren < maxChildren) {
  286.         status = RunChild(mountCount, numChecks, childInfo, &i);
  287.         if (status == FAILURE) {
  288.         if (i < 0) {
  289.             /*
  290.              * There are no available jobs that can be run.
  291.              * Wait for some to finish.
  292.              */
  293.             assert(activeChildren > 0);
  294.             break;
  295.         }
  296.         /*
  297.          * Some sort of error occurred.
  298.          */
  299.         mountTable[i].doCheck = FALSE;
  300.         returnCode = HARDERROR;
  301.         doneChildren++;
  302.         } else {
  303.         mountTable[i].status = CHILD_RUNNING;
  304.         groupInfo[mountTable[i].group].running = TRUE;
  305.         activeChildren++;
  306.         if (sequential) {
  307.             break;
  308.         }
  309.         }
  310.     }
  311.     if (activeChildren > 0) {
  312.         if (printOnly) {
  313.         for (i = 0; i < mountCount; i++) {
  314.             if (mountTable[i].status == CHILD_RUNNING) {
  315.             break;
  316.             }
  317.         }
  318.         assert(i != numChecks);
  319.         childPid = i;
  320.         } else {
  321.         childPid = wait(&waitStatus);
  322.         }
  323.         activeChildren--;
  324.         for (i = 0; i < numChecks; i++) {
  325.         if (childInfo[i].pid == childPid) {
  326.             mountPtr = &(mountTable[childInfo[i].mountIndex]);
  327.             childInfo[i].pid = -1;
  328.             break;
  329.         }
  330.         }
  331.         if (verbose) {
  332.         printf("Fscheck of %s finished.\n", mountPtr->source);
  333.         }
  334.         if (printOnly) {
  335.         doneChildren++;
  336.         mountPtr->status = CHILD_OK;
  337.         mountPtr->doCheck = FALSE;
  338.         groupInfo[mountPtr->group].running = FALSE;
  339.         continue;
  340.         }
  341.         if (WIFEXITED(waitStatus) && 
  342.         waitStatus.w_retcode == FSCHECK_OUT_OF_MEMORY) {
  343.         continue;
  344.         }
  345.         doneChildren++;
  346.         mountPtr->doCheck = FALSE;
  347.         mountPtr->checked = TRUE;
  348.         groupInfo[mountPtr->group].running = FALSE;
  349.         if (WIFSIGNALED(waitStatus) || WIFSTOPPED(waitStatus)) {
  350.         (void) fprintf(stderr,"%s did not finish.\n", fscheck);
  351.         returnCode = HARDERROR;
  352.         mountPtr->status = CHILD_FAILURE;
  353.         } else if (waitStatus.w_retcode == EXEC_FAILED) {
  354.         returnCode = HARDERROR;
  355.         mountPtr->status = CHILD_FAILURE;
  356.         } else {
  357.         if (debug) {
  358.             printf("%s returned 0x%x.\n", fscheck,
  359.             (unsigned int) waitStatus.w_retcode);
  360.             printf("returnCode is %d.\n", returnCode);
  361.         }
  362.         mountPtr->status = CHILD_OK;
  363.         if ((char) waitStatus.w_retcode < 0 ) {
  364.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  365.             mountPtr->status = CHILD_FAILURE;
  366.             returnCode = HARDERROR;
  367.         } else if ((char) waitStatus.w_retcode > 0) {
  368.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  369.             if ((char) waitStatus.w_retcode == FSCHECK_REBOOT) {
  370.             reboot = TRUE;
  371.             }
  372.             if (returnCode == OK) {
  373.             returnCode = SOFTERROR;
  374.             }
  375.         } else if (verbose) {
  376.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  377.         }
  378.         }
  379.     }
  380.     }
  381.     assert(doneChildren == numChecks);
  382.     assert(activeChildren == 0);
  383. }
  384.  
  385. /*
  386.  *----------------------------------------------------------------------
  387.  *
  388.  * CacheWriteBack --
  389.  *
  390.  *    Turns cache write-back on and off
  391.  * Results:
  392.  *    None.
  393.  *
  394.  * Side effects:
  395.  *    The cache write-back status is changed.
  396.  *
  397.  *----------------------------------------------------------------------
  398.  */
  399.  
  400. void
  401. CacheWriteBack(value)
  402.     int        value;
  403. {
  404.  
  405.     int            newValue;
  406.     ReturnStatus    status;
  407.     int            lockedBlocks;
  408.  
  409.     if (printOnly && verbose) {
  410.     printf("Setting cache write-back to %d.\n", value);
  411.     return;
  412.     }
  413.     if (!writeDisk) {
  414.     if (verbose) {
  415.         fprintf(stderr, 
  416.             "Fscheck not writing disks -- not changing  write-back.\n");
  417.     }
  418.     return;
  419.     }
  420.     newValue = value;
  421.     status = Fs_Command(FS_DISABLE_FLUSH, sizeof(int), (Address) &value);
  422.     if (status != SUCCESS) {
  423.     (void) fprintf(stderr, "Fs_Command (1)  returned %d.\n", status);
  424.     (void) exit(HARDERROR);
  425.     }
  426.     if (verbose) {
  427.     (void) fprintf(stderr, "Cache write-back %s, was %s.\n", 
  428.         (newValue) ? "on" : "off",
  429.             (value) ? "on" : "off");
  430.     }
  431.     /*
  432.      * If we're turning the write-back off flush what's in the cache already.
  433.      */
  434.     if (newValue == 0) {
  435.     status = Fs_Command(FS_EMPTY_CACHE, sizeof(int), 
  436.             (Address) &lockedBlocks);
  437.     if (status != SUCCESS) {
  438.         (void) fprintf(stderr, "Fs_Command (2)  returned %d.\n", status);
  439.         (void) exit(HARDERROR);
  440.     }
  441.     if (lockedBlocks > 0) {
  442.         fprintf(stderr, "There are %d locked blocks in the cache ?!\n", 
  443.         lockedBlocks);
  444.     }
  445.     }
  446. }
  447.  
  448. /*
  449.  *----------------------------------------------------------------------
  450.  *
  451.  * RunChild --
  452.  *
  453.  *    Forks a process to run fscheck.
  454.  *
  455.  * Results:
  456.  *    None.
  457.  *
  458.  * Side effects:
  459.  *    A process is forked.
  460.  *
  461.  *----------------------------------------------------------------------
  462.  */
  463.  
  464. ReturnStatus
  465. RunChild(mountCount, numChecks, childInfo, mountIndexPtr)
  466.     int        mountCount;        /* # entries in mount table */
  467.     int        numChecks;        /* # of jobs to run */
  468.     ChildInfo    *childInfo;        /* info on running children */
  469.     int        *mountIndexPtr;        /* ptr to index into mount table */
  470. {
  471.     int        mountIndex;
  472.     int        i;
  473.     MountInfo    *mountPtr = NULL;
  474.     static char    deviceName[MAX_FIELD_LENGTH];
  475.     static char    partition[MAX_FIELD_LENGTH];
  476.     static char    outputFile[MAX_FIELD_LENGTH];
  477.     int        pid;
  478.     ArgHeader    *argPtr;
  479.     Boolean    defaultOutputFile = TRUE;
  480.     Boolean    defaultRootPart = TRUE;
  481.     Boolean    defaultDir = TRUE;
  482.  
  483.     /*
  484.      * Find a child to run.
  485.      */
  486.     *mountIndexPtr = -1;
  487.     for (mountIndex = 0; mountIndex < mountCount; mountIndex++) {
  488.     if (mountTable[mountIndex].group == 0 &&
  489.         mountTable[mountIndex].status == CHILD_RUNNING) {
  490.         break;
  491.     }
  492.     if ((mountTable[mountIndex].doCheck) &&
  493.         (groupInfo[mountTable[mountIndex].group].running == FALSE) &&
  494.         (mountTable[mountIndex].status != CHILD_RUNNING)) {
  495.         mountPtr = &(mountTable[mountIndex]);
  496.         break;
  497.     }
  498.     }
  499.     if (mountPtr == NULL) {
  500.     return FAILURE;
  501.     }
  502.     *mountIndexPtr = mountIndex;
  503.     /*
  504.      * Put together the arguments to fscheck.
  505.      */
  506.     (void) strcpy(partition, &(mountPtr->source[strlen(mountPtr->source) -1 ]));
  507.     (void) strcpy(deviceName, mountPtr->source);
  508.     deviceName[strlen(mountPtr->source) - 1] = '\0';
  509.     StartExec(fscheck, fscheck);
  510.     AddExecArgs("-dev", deviceName, NULL);
  511.     AddExecArgs("-part", partition, NULL);
  512.     LIST_FORALL((List_Links *) &mountPtr->argInfo.argList, 
  513.     (List_Links *) argPtr) {
  514.     if (!strcmp("-verbose", argPtr->arg) && verbose) {
  515.         continue;
  516.     } else if (!strcmp(argPtr->arg, "-write") && !writeDisk) {
  517.         continue;
  518.     } else if (!strcmp("-dir", argPtr->arg)) {
  519.         defaultDir = FALSE;
  520.     }
  521.     AddExecArgs(argPtr->arg, NULL);
  522.     }
  523.     DeleteList(&mountPtr->argInfo.argList);
  524.     if (verbose) {
  525.     AddExecArgs("-verbose", NULL);
  526.     }
  527.     if (writeDisk) {
  528.     AddExecArgs("-write", NULL);
  529.     }
  530.     AddExecArgs("-outputFile", tempOutputFile, NULL);
  531.     AddExecArgs("-rawOutput", NULL);
  532.     if (condCheck) {
  533.     AddExecArgs("-cond", "-setCheck", NULL);
  534.     }
  535.     if (defaultDir) {
  536.     AddExecArgs("-dir", devDir, NULL);
  537.     }
  538.     pid = DoExec();
  539.     if (pid < 0) {
  540.     if (verbose) {
  541.         fprintf(stderr, "Fork of child failed.\n");
  542.         perror("");
  543.     }
  544.     return FAILURE;
  545.     }
  546.     /*
  547.      * Store info about the running child.
  548.      */
  549.     for (i = 0; i < numChecks; i++) {
  550.     if (childInfo[i].pid == -1) {
  551.         if (printOnly) {
  552.         childInfo[i].pid = mountIndex;
  553.         } else {
  554.         childInfo[i].pid = pid;
  555.         }
  556.         childInfo[i].mountIndex = mountIndex;
  557.         break;
  558.     }
  559.     }
  560.     assert(i != numChecks);
  561.     return SUCCESS;
  562. }
  563.  
  564. /*
  565.  *----------------------------------------------------------------------
  566.  *
  567.  * Prefix --
  568.  *
  569.  *    Adds all devices that were checked correctly to the prefix table.
  570.  *
  571.  * Results:
  572.  *    None.
  573.  *
  574.  * Side effects:
  575.  *    Entries are added to the system prefix table.
  576.  *
  577.  *----------------------------------------------------------------------
  578.  */
  579.  
  580. void
  581. Prefix(count)
  582.     int        count;        /* # entries in mount table */
  583. {
  584.     int            i;
  585.     ReturnStatus    status;
  586.     int            flags;
  587.     Fs_TwoPaths        paths;
  588.     char        buffer[128];
  589.     char        *source;
  590.     char        *dest;
  591.     Boolean        device;
  592.     char        *prefix;
  593.  
  594.     for (i = 0; i < count; i ++) {
  595.     if (mountTable[i].status == CHILD_OK) {
  596.         flags = 0;
  597.         if (mountTable[i].readonly) {
  598.         flags |= FS_ATTACH_READ_ONLY;
  599.         }
  600.         if (mountTable[i].export == FALSE) {
  601.         flags |= FS_ATTACH_LOCAL;
  602.         }
  603.         source = mountTable[i].source;
  604.         dest = mountTable[i].dest;
  605.         device = mountTable[i].device;
  606.         /*
  607.          * Use Fs_AttachDisk to attach a disk.
  608.          */
  609.         if (device == TRUE) {
  610.         printf("Attaching %s%s as %s.\n", devDir, source, dest);
  611.         printf("%s %s.\n", mountTable[i].readonly ? "R" : "RW",
  612.                mountTable[i].export ? "Export" : "Local");
  613.         if (printOnly) {
  614.             continue;
  615.         }
  616.         sprintf(buffer, "%s%s", devDir, source);
  617.  
  618.         status = Fs_AttachDisk(buffer, dest, flags);
  619.         if (status == FS_DOMAIN_UNAVAILABLE) {
  620.             printf("%s is already attached.\n", buffer);
  621.             prefix = GetAttachName(buffer);
  622.             if (prefix != NULL) {
  623.             source = prefix;
  624.             device = FALSE;
  625.             }
  626.         } else if (status != SUCCESS) {
  627.             (void) fprintf(stderr, "Attach \"%s\" on \"%s\": %s\n", 
  628.                 buffer, dest, Stat_GetMsg(status));
  629.         }
  630.         }
  631.         if (device == FALSE) {
  632.         printf("Exporting %s as %s.\n", source, dest);
  633.         if (printOnly) {
  634.             continue;
  635.         }
  636.         paths.pathLen1 = strlen(source) +1;
  637.         paths.path1 = source;
  638.         paths.pathLen2 = strlen(dest) +1;
  639.         paths.path2 = dest;
  640.         status = Fs_Command(FS_PREFIX_EXPORT, sizeof(paths), 
  641.                         (Address) &paths);
  642.         if (status != SUCCESS) {
  643.             fprintf(stderr, 
  644.                 "Couldn't export  \"%s\" as \"%s\": %s\n",
  645.                 source, dest, Stat_GetMsg(status));
  646.         }
  647.         }
  648.     }
  649.     }
  650. }
  651. @
  652.  
  653.  
  654. 1.9
  655. log
  656. @Added -fscheck option to allow alternative fscheck program.
  657. @
  658. text
  659. @d21 1
  660. a21 1
  661. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.7 89/11/29 16:19:47 ouster Exp Locker: jhh $ SPRITE (Berkeley)";
  662. a27 1
  663. char *bootPrefix = "/bootTmp";
  664. d38 1
  665. a40 2
  666.     {OPT_STRING,   "b", (char *) &bootPrefix,
  667.     "Prefix under which first partition is attached during boot."},
  668. d60 1
  669. a60 1
  670.     "Ignore pass information and run fscheck sequentially."},
  671. d65 2
  672. d81 2
  673. a82 2
  674. char        *rootTempOutputFile = ".fscheck.out";
  675. int        rootTempOutputFileSize = 8192;
  676. d85 1
  677. d154 1
  678. d156 6
  679. d166 2
  680. d279 1
  681. d301 3
  682. a310 33
  683.         if (mountTable[childInfo[i].mountIndex].group == 0) {
  684.     /*
  685.      * If there was a soft error doing the root partition we may have
  686.      * to reboot.  Re-enable cache write-backs EXCEPT in the case
  687.      * where errors were fixed and a re-boot is needed;  in this
  688.      * case leave write-backs off, so that bad old data from the
  689.      * cache can't overwrite the new good data.
  690.      */
  691.         if (returnCode == SOFTERROR) {
  692.             if (writeDisk) {
  693.             if (waitStatus.w_retcode != FSCHECK_NOREBOOT) {
  694.                 if (debug) {
  695.                 printf("(4) Exiting with %d.\n", REBOOT);
  696.                 }
  697.                 (void) exit(REBOOT);
  698.             } else {
  699.                 if (debug) {
  700.                 printf("(2) Exiting with %d.\n", NOREBOOT);
  701.                 }
  702.                 CacheWriteBack(TRUE);
  703.                 (void) exit(NOREBOOT);
  704.             }
  705.             }
  706.         } else if (returnCode != OK) {
  707.             if (debug) {
  708.             printf("(3) Exiting with %d.\n", HARDERROR);
  709.             }
  710.             CacheWriteBack(TRUE);
  711.             exit(HARDERROR);
  712.         }
  713.         CacheWriteBack(TRUE);
  714.         MoveRootOutput(mountPtr->source);
  715.         }
  716. a435 13
  717.      * This code is kind is a special-case handling of the root partition.
  718.      * It should be able to go away with the new boot sequence.
  719.      * There will be no need to check the root partition first.
  720.      */
  721.     if (mountTable[mountIndex].group == 0) {
  722.         /*
  723.          * We are doing the root partition, which has already been mounted
  724.          * as part of the boot. We don't want the cache to write back over
  725.          * the disk as we are fixing it, so turn cache write-back off.
  726.          */
  727.         CacheWriteBack(FALSE);
  728.     }
  729.     /*
  730. a449 4
  731.     } else if (!strcmp("-outputFile", argPtr->arg)) {
  732.         defaultOutputFile = FALSE;
  733.     } else if (!strcmp("-rootPart", argPtr->arg)) {
  734.         defaultRootPart = FALSE;
  735. d462 4
  736. a465 12
  737.     (void) sprintf(outputFile, "/hosts/%s/%s%s.fsc", getenv("HOST"), 
  738.         deviceName, partition);
  739.     if (defaultOutputFile) {
  740.     AddExecArgs("-outputFile", NULL);
  741.     if (mountPtr->group == 0) {
  742.         AddExecArgs(rootTempOutputFile,NULL);
  743.     } else {
  744.         AddExecArgs(outputFile, NULL);
  745.     }
  746.     }
  747.     if (defaultRootPart && mountPtr->group == 0) {
  748.     AddExecArgs("-rootPart", NULL);
  749. d521 4
  750. d535 3
  751. d541 2
  752. a542 3
  753.         if (mountTable[i].device == TRUE && mountTable[i].group != 0) {
  754.         printf("Attaching %s%s as %s.\n", devDir, 
  755.                    mountTable[i].source, mountTable[i].dest);
  756. d548 11
  757. a558 3
  758.         sprintf(buffer, "%s%s", devDir, mountTable[i].source);
  759.         status = Fs_AttachDisk(buffer, mountTable[i].dest, flags);
  760.         if (status != SUCCESS) {
  761. d560 1
  762. a560 1
  763.                 buffer, mountTable[i].dest, Stat_GetMsg(status));
  764. d562 3
  765. a564 16
  766.         /*
  767.          * Use Fs_Command to export a prefix under a different name.
  768.          * The first partition is a bit funny since it was already
  769.          * attached under a different name.  We need to export its
  770.          * new name, even though it is an attach command in the
  771.          * mount table rather than an export command.
  772.          */
  773.         } else {
  774.         char *source;
  775.         if (mountTable[i].group == 0) {
  776.             source = bootPrefix;
  777.         } else {
  778.             source = mountTable[i].source;
  779.         }
  780.         printf("Exporting %s as %s.\n", 
  781.                    source, mountTable[i].dest);
  782. d570 2
  783. a571 2
  784.         paths.pathLen2 = strlen(mountTable[i].dest) +1;
  785.         paths.path2 = mountTable[i].dest;
  786. d577 1
  787. a577 2
  788.                 source, mountTable[i].dest, 
  789.                 Stat_GetMsg(status));
  790. a582 1
  791.  
  792. @
  793.  
  794.  
  795. 1.8
  796. log
  797. @Uses groups instead of passes
  798. @
  799. text
  800. @d29 1
  801. d45 2
  802. d271 1
  803. a271 1
  804.         (void) fprintf(stderr,"fscheck did not finish.\n");
  805. d279 1
  806. a279 1
  807.             printf("fscheck returned 0x%x.\n", 
  808. d473 1
  809. a473 1
  810.     StartExec("fscheck", "fscheck");
  811. @
  812.  
  813.  
  814. 1.7
  815. log
  816. @Lint.
  817. @
  818. text
  819. @d21 1
  820. a21 1
  821. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.6 89/11/29 16:16:53 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  822. d37 1
  823. d40 2
  824. a41 2
  825.     {OPT_STRING,   "m", (char *) &mountFile,
  826.     "File containing disk<=>prefix information."},
  827. a43 4
  828.     {OPT_STRING,   "b", (char *) &bootPrefix,
  829.     "Prefix under which first partition is attached during boot."},
  830.     {OPT_FALSE,   "W", (char *) &writeDisk,
  831.     "Don't let fscheck write to the disks."},
  832. d46 12
  833. d62 2
  834. a63 8
  835.     {OPT_TRUE,   "n", (char *) &nomount,
  836.     "No mount."},
  837.     {OPT_TRUE,   "p", (char *) &printOnly,
  838.     "Don't do anything. Just print out actions."},
  839.     {OPT_TRUE,   "k", (char *) &debug,
  840.     "Print debugging output."},
  841.     {OPT_INT,   "i", (char *) &spriteID,
  842.     "Preload prefix table with ourself as server of prefixes we export"},
  843. d74 4
  844. a77 2
  845. int        *partsToDo;
  846. int        maxPass;
  847. d110 1
  848. a110 1
  849.     int            maxChildren;
  850. d121 5
  851. a132 5
  852.     Alloc(partsToDo, int, maxPass+1, "partsToDo");
  853.     assert(partsToDo != NULL);
  854.     for (i = 0; i <= maxPass; i++) {
  855.     partsToDo[i] = 0;
  856.     }
  857. d138 1
  858. d146 1
  859. a146 1
  860.         partsToDo[mountTable[i].pass]++;
  861. a148 9
  862.     /*
  863.      * Find the maximum children per pass.
  864.      */
  865.     maxChildren = 0;
  866.     for (i = 0; i <= maxPass; i++) {
  867.     if (partsToDo[i] > maxChildren) {
  868.         maxChildren = partsToDo[i];
  869.     }
  870.     }
  871. d150 1
  872. a150 1
  873.     CheckDisks(mountCount, maxChildren);
  874. d179 1
  875. a179 1
  876. CheckDisks(mountCount, maxChildren)
  877. d181 1
  878. a181 1
  879.     int            maxChildren;    /* max children per pass */
  880. d193 1
  881. a193 1
  882.     Alloc(childInfo, ChildInfo, maxChildren, "childInfo");
  883. d195 1
  884. a195 1
  885.     for (i = 0; i < maxChildren; i++) {
  886. d198 29
  887. a226 28
  888.     for (pass = 0; pass <= maxPass; pass++) {
  889.     if (partsToDo[pass] == 0) {
  890.         continue;
  891.     }
  892.     if (verbose) {
  893.         fprintf(stderr,"Pass %d.\n", pass);
  894.     }
  895.     if (pass == 0) {
  896.         /*
  897.          * We are doing the root partition, which has already been mounted
  898.          * as part of the boot. We don't want the cache to write back over
  899.          * the disk as we are fixing it, so turn cache write-back off.
  900.          */
  901.         CacheWriteBack(FALSE);
  902.     }
  903.     activeChildren = 0;
  904.     doneChildren = 0;
  905.     while (doneChildren < partsToDo[pass]) {
  906.         while (activeChildren < partsToDo[pass] - doneChildren &&
  907.            (!sequential || (sequential && activeChildren < 1))) {
  908.         status = RunChild(pass, mountCount, maxChildren, childInfo, &i);
  909.         if (status == FAILURE) {
  910.             mountTable[i].doCheck = FALSE;
  911.             returnCode = HARDERROR;
  912.             doneChildren++;
  913.         } else {
  914.             mountTable[i].status = CHILD_RUNNING;
  915.             activeChildren++;
  916. d229 5
  917. a233 11
  918.         if (activeChildren > 0) {
  919.         if (printOnly) {
  920.             childPid = i;
  921.         } else {
  922.             childPid = wait(&waitStatus);
  923.         }
  924.         activeChildren--;
  925.         for (i = 0; i < partsToDo[pass]; i++) {
  926.             if (childInfo[i].pid == childPid) {
  927.             mountPtr = &(mountTable[childInfo[i].mountIndex]);
  928.             childInfo[i].pid = -1;
  929. d237 11
  930. a247 5
  931.         if (printOnly) {
  932.             doneChildren++;
  933.             mountPtr->status = CHILD_OK;
  934.             mountPtr->doCheck = FALSE;
  935.             continue;
  936. d249 5
  937. a253 4
  938.         if (WIFEXITED(waitStatus) && 
  939.             waitStatus.w_retcode == FSCHECK_OUT_OF_MEMORY) {
  940.             continue;
  941.         }
  942. d255 1
  943. d257 26
  944. a282 3
  945.         if (WIFSIGNALED(waitStatus) || WIFSTOPPED(waitStatus)) {
  946.             (void) fprintf(stderr,"fscheck did not finish.\n");
  947.             returnCode = HARDERROR;
  948. a283 1
  949.         } else if (waitStatus.w_retcode == EXEC_FAILED) {
  950. d285 4
  951. a288 19
  952.             mountPtr->status = CHILD_FAILURE;
  953.         } else {
  954.             if (debug) {
  955.             printf("fscheck returned 0x%x.\n", 
  956.                 (unsigned int) waitStatus.w_retcode);
  957.             printf("returnCode is %d.\n", returnCode);
  958.             }
  959.             mountPtr->status = CHILD_OK;
  960.             if ((char) waitStatus.w_retcode < 0 ) {
  961.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  962.             mountPtr->status = CHILD_FAILURE;
  963.             returnCode = HARDERROR;
  964.             } else if ((char) waitStatus.w_retcode > 0) {
  965.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  966.             if (returnCode == OK) {
  967.                 returnCode = SOFTERROR;
  968.             }
  969.             } else if (verbose) {
  970.             PrintFscheckError((char)waitStatus.w_retcode, mountPtr);
  971. d290 2
  972. d294 21
  973. a314 16
  974.     }
  975.     assert(doneChildren == partsToDo[pass]);
  976.     assert(activeChildren == 0);
  977.     if (pass == 0) {
  978.         /*
  979.          * If there was a soft error doing the root partition we may have
  980.          * to reboot.  Re-enable cache write-backs EXCEPT in the case
  981.          * where errors were fixed and a re-boot is needed;  in this
  982.          * case leave write-backs off, so that bad old data from the
  983.          * cache can't overwrite the new good data.
  984.          */
  985.         if (returnCode == SOFTERROR) {
  986.         if (writeDisk) {
  987.             if (waitStatus.w_retcode != FSCHECK_NOREBOOT) {
  988.             if (debug) {
  989.                 printf("(4) Exiting with %d.\n", REBOOT);
  990. d316 4
  991. a319 7
  992.             (void) exit(REBOOT);
  993.             } else {
  994.             if (debug) {
  995.                 printf("(2) Exiting with %d.\n", NOREBOOT);
  996.             }
  997.             CacheWriteBack(TRUE);
  998.             (void) exit(NOREBOOT);
  999. d321 2
  1000. a323 4
  1001.         } else if (returnCode != OK) {
  1002.         if (debug) {
  1003.             printf("(3) Exiting with %d.\n", HARDERROR);
  1004.         }
  1005. d325 1
  1006. a325 1
  1007.         exit(HARDERROR);
  1008. a326 2
  1009.         CacheWriteBack(TRUE);
  1010.         MoveRootOutput(mountPtr->source);
  1011. d329 2
  1012. d413 1
  1013. a413 2
  1014. RunChild(pass, mountCount, maxChildren, childInfo, mountIndexPtr)
  1015.     int        pass;            /* pass we're doing */
  1016. d415 1
  1017. a415 1
  1018.     int        maxChildren;        /* max children per pass */
  1019. d434 1
  1020. d436 7
  1021. a442 4
  1022.     if (mountTable[mountIndex].pass == pass && 
  1023.         mountTable[mountIndex].doCheck &&
  1024.         mountTable[mountIndex].status != CHILD_RUNNING) {
  1025.  
  1026. d447 3
  1027. a449 1
  1028.     assert(mountPtr != NULL);
  1029. d452 13
  1030. d499 1
  1031. a499 1
  1032.     if (mountPtr->pass == 0) {
  1033. d505 1
  1034. a505 1
  1035.     if (defaultRootPart && mountPtr->pass == 0) {
  1036. d522 1
  1037. a522 1
  1038.     for (i = 0; i < maxChildren; i++) {
  1039. d533 1
  1040. a533 1
  1041.     assert(i != maxChildren);
  1042. d575 1
  1043. a575 1
  1044.         if (mountTable[i].device == TRUE && mountTable[i].pass != 0) {
  1045. d598 1
  1046. a598 1
  1047.         if (mountTable[i].pass == 0) {
  1048. @
  1049.  
  1050.  
  1051. 1.6
  1052. log
  1053. @Don't re-enable cache write-backs if a re-boot is in order:
  1054. disk might get corrupted.
  1055. @
  1056. text
  1057. @d21 1
  1058. a21 1
  1059. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.5 89/10/25 18:06:42 jhh Exp $ SPRITE (Berkeley)";
  1060. d51 1
  1061. a51 1
  1062.     {OPT_TRUE,   "v", (int *) &verbose,
  1063. d59 1
  1064. a59 1
  1065.     {OPT_INT,   "i", (int *) &spriteID,
  1066. @
  1067.  
  1068.  
  1069. 1.5
  1070. log
  1071. @exporting of root partition is now cleaner.
  1072. @
  1073. text
  1074. @d5 4
  1075. a8 4
  1076.  *    uses a mount file in /local/bootBin that indicates what
  1077.  *    prefixes/disks to attach.  This also siphons off some
  1078.  *    availability/reliability information that is put in the summary
  1079.  *    information sector on each disk.
  1080. d21 1
  1081. a21 1
  1082. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.4 89/06/19 14:21:22 jhh Exp $ SPRITE (Berkeley)";
  1083. a288 1
  1084.         CacheWriteBack(TRUE);
  1085. d291 4
  1086. a294 1
  1087.          * to reboot.
  1088. d307 1
  1089. d315 1
  1090. d318 1
  1091. @
  1092.  
  1093.  
  1094. 1.4
  1095. log
  1096. @Added stuff to preload prefix table
  1097. @
  1098. text
  1099. @d21 1
  1100. a21 1
  1101. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.3 89/06/07 22:14:31 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  1102. d28 1
  1103. d43 2
  1104. d59 1
  1105. a59 1
  1106.     {OPT_INT,   "i", (char *) &spriteID,
  1107. d463 2
  1108. a464 1
  1109.     (void) sprintf(outputFile, "%s%s.fsc", deviceName, partition);
  1110. d532 1
  1111. a532 1
  1112.     if (mountTable[i].status == CHILD_OK && mountTable[i].pass != 0) {
  1113. d543 5
  1114. a547 7
  1115.         if (mountTable[i].device == TRUE) {
  1116.         if (verbose) {
  1117.             printf("Attaching %s%s as %s.\n", devDir, 
  1118.                    mountTable[i].source, mountTable[i].dest);
  1119.             printf("%s %s.\n", mountTable[i].readonly ? "R" : "RW",
  1120.                mountTable[i].export ? "Export" : "Local");
  1121.         }
  1122. d553 1
  1123. a553 1
  1124.         if (verbose && status != SUCCESS) {
  1125. d559 4
  1126. d565 5
  1127. a569 3
  1128.         if (verbose) {
  1129.             printf("Exporting %s as %s.\n", 
  1130.                    mountTable[i].source, mountTable[i].dest);
  1131. d571 2
  1132. d576 2
  1133. a577 2
  1134.         paths.pathLen1 = strlen(mountTable[i].source) +1;
  1135.         paths.path1 = mountTable[i].source;
  1136. d582 1
  1137. a582 1
  1138.         if (verbose && status != SUCCESS) {
  1139. d585 1
  1140. a585 1
  1141.                 mountTable[i].source, mountTable[i].dest, 
  1142. @
  1143.  
  1144.  
  1145. 1.3
  1146. log
  1147. @Spring cleaning - new mount table format, bug fixes
  1148. @
  1149. text
  1150. @d21 1
  1151. a21 1
  1152. static char rcsid[] = "$Header: /sprite/src/admin/fsattach/RCS/fsattach.c,v 1.2 89/04/10 11:12:22 jhh Exp $ SPRITE (Berkeley)";
  1153. d35 1
  1154. a37 4
  1155. #if 0
  1156.     {OPT_STRING,   "c", (char *) &configFile,
  1157.     "File containing fsattach configuration information."},
  1158. #endif
  1159. d56 2
  1160. d116 3
  1161. @
  1162.  
  1163.  
  1164. 1.2
  1165. log
  1166. @First working version
  1167. @
  1168. text
  1169. @d21 1
  1170. a21 1
  1171. static char rcsid[] = "$Header: /sprite/users/jhh/fsattach/RCS/fsattach.c,v 1.1 89/03/06 12:58:45 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  1172. d26 3
  1173. a28 3
  1174. char *mountFile = "/local/bootBin/mount";
  1175. char *configFile = "/local/bootBin/fsattach.config";
  1176. Boolean verbose = FALSE;
  1177. d34 1
  1178. d37 1
  1179. d40 1
  1180. d43 2
  1181. d51 2
  1182. a52 2
  1183.     {OPT_TRUE,   "v", (char *) &verbose,
  1184.     "Verbose mode."},
  1185. d57 2
  1186. d66 2
  1187. a67 1
  1188. int         mountTableSize = DEFAULT_MAX_MOUNT_ENTRIES;
  1189. d71 4
  1190. a74 5
  1191. char        *rootTempOutputFile = DEFAULT_ROOT_TEMP_NAME;
  1192. char        *outputDir = DEFAULT_OUTPUT_DIR;
  1193. char        *heapLimitString = DEFAULT_HEAP_LIMIT;
  1194. int        rootTempOutputFileSize = DEFAULT_ROOT_TEMP_SIZE;
  1195. char        *fscheckPath = DEFAULT_FSCHECK_PATH;
  1196. a108 1
  1197.     status = ParseConfig(configFile);
  1198. d118 1
  1199. a118 1
  1200.     Alloc(partsToDo, int, maxPass, "partsToDo");
  1201. d153 3
  1202. d194 1
  1203. a194 1
  1204.     childInfo[i].pid = 0;
  1205. a225 4
  1206.         if (printOnly) {
  1207.         printf("Waiting.\n");
  1208.         continue;
  1209.         }
  1210. d227 5
  1211. a231 1
  1212.         childPid = wait(&waitStatus);
  1213. d236 1
  1214. a236 1
  1215.             childInfo[i].pid = 0;
  1216. d240 6
  1217. d260 5
  1218. d292 9
  1219. a300 1
  1220.             returnCode = REBOOT;
  1221. a301 1
  1222.             (void) exit(NOREBOOT);
  1223. d304 3
  1224. d336 1
  1225. d338 1
  1226. a338 1
  1227.     if (printOnly) {
  1228. d352 1
  1229. a352 1
  1230.     (void) fprintf(stderr, "Fs_Command returned %d.\n", status);
  1231. d360 15
  1232. a404 1
  1233.     static char    deviceDir[MAX_FIELD_LENGTH];
  1234. d408 4
  1235. a431 1
  1236.     (void) strcpy(deviceDir, mountPtr->source);
  1237. d433 15
  1238. a447 5
  1239.     for(i = strlen(deviceName) - 1; i >= 0; i--) {
  1240.     if (deviceName[i] == '/') {
  1241.         deviceDir[i+1] = '\0';
  1242.         i++;
  1243.         break;
  1244. d449 1
  1245. d451 1
  1246. a451 7
  1247.     (void) sprintf(outputFile, "%s/%s%s.fsc", outputDir, &(deviceName[i]),
  1248.                partition);
  1249.     StartExec(fscheckPath, "fscheck");
  1250.     AddExecArgs("-dev", &(deviceName[i]),NULL);
  1251.     AddExecArgs("-part", partition, NULL);
  1252.     AddExecArgs("-dir", deviceDir, NULL);
  1253.     AddExecArgs("-heapLimit", heapLimitString, NULL);
  1254. d458 14
  1255. a471 5
  1256.     AddExecArgs("-outputFile", NULL);
  1257.     if (mountPtr->pass == 0) {
  1258.     AddExecArgs(rootTempOutputFile, "-rootPart", NULL);
  1259.     } else {
  1260.     AddExecArgs(outputFile, NULL);
  1261. d485 6
  1262. a490 2
  1263.     if (childInfo[i].pid == 0) {
  1264.         childInfo[i].pid = pid;
  1265. d504 1
  1266. a504 1
  1267.  *    Adds all devices that where checked correctly to the prefix table.
  1268. d523 1
  1269. a523 2
  1270.     struct stat        buf;
  1271.     int            statStatus;
  1272. a526 11
  1273.         statStatus = lstat(mountTable[i].dest, &buf);
  1274.         if (statStatus) {
  1275.         (void) fprintf(stderr, "Can't lstat %s.\n", mountTable[i].dest);
  1276.         perror("");
  1277.         continue;
  1278.         }
  1279.         if (!(buf.st_mode & S_IFRLNK)) {
  1280.         fprintf(stderr, "%s is not a remote link.\n", 
  1281.             mountTable[i].dest);
  1282.         continue;
  1283.         }
  1284. d535 1
  1285. a535 1
  1286.          * Use Fs_AttachDisk to export a disk.
  1287. d538 2
  1288. a539 2
  1289.         if (printOnly) {
  1290.             printf("Attaching %s as %s.\n", 
  1291. d543 2
  1292. d547 2
  1293. a548 2
  1294.         status = Fs_AttachDisk(mountTable[i].source, 
  1295.                        mountTable[i].dest, flags);
  1296. d550 2
  1297. a551 3
  1298.             (void) fprintf(stderr, "Mount \"%s\" on \"%s\": %s\n", 
  1299.                 mountTable[i].source, mountTable[i].dest, 
  1300.                 Stat_GetMsg(status));
  1301. d557 1
  1302. a557 1
  1303.         if (printOnly) {
  1304. d560 2
  1305. @
  1306.  
  1307.  
  1308. 1.1
  1309. log
  1310. @Initial revision
  1311. @
  1312. text
  1313. @d21 1
  1314. a21 1
  1315. static char rcsid[] = "$Header: df.c,v 1.3 88/09/23 17:50:38 ouster Exp $ SPRITE (Berkeley)";
  1316. d33 1
  1317. d38 1
  1318. a38 1
  1319.     {OPT_STRING,   "f", (char *) &mountFile,
  1320. d42 2
  1321. d67 1
  1322. a102 3
  1323.     if (status != SUCCESS) {
  1324.     (void) exit(HARDERROR);
  1325.     }
  1326. d106 1
  1327. a106 7
  1328.     mountTable[i].status = OK;
  1329.     mountTable[i].pass = -1;
  1330.     mountTable[i].device = TRUE;
  1331.     mountTable[i].doCheck = TRUE;
  1332.     mountTable[i].root = FALSE;
  1333.     mountTable[i].export = TRUE;
  1334.     mountTable[i].readonly = FALSE;
  1335. d108 3
  1336. a110 2
  1337.     if (verbose) {
  1338.     (void) printf("%-20s %-10s\n", "Prefix", "Device");
  1339. a111 1
  1340.     ParseMount(mountFile, &mountCount);
  1341. d114 1
  1342. a114 1
  1343.     for (i = 0; i < maxPass; i++) {
  1344. d117 5
  1345. d123 3
  1346. a125 8
  1347.     for (j = 0; j < mountCount; j++) {
  1348.         if (!strcmp(mountTable[i].source, mountTable[j].dest)) {
  1349.         mountTable[i].device = FALSE;
  1350.         mountTable[i].doCheck = FALSE;
  1351.         }
  1352.         if (!strcmp(mountTable[i].source, mountTable[j].source) &&
  1353.             i != j) {
  1354.         mountTable[max(i,j)].doCheck = FALSE;
  1355. a127 2
  1356.     }
  1357.     for (i = 0; i < mountCount; i++) {
  1358. d132 3
  1359. d136 1
  1360. a136 1
  1361.     for (i = 0; i < maxPass; i++) {
  1362. d141 3
  1363. a143 1
  1364.     CheckDisks(mountCount, maxChildren);
  1365. d155 2
  1366. a156 1
  1367.  *    description.
  1368. d159 1
  1369. a159 1
  1370.  *    None.
  1371. d162 1
  1372. a162 1
  1373.  *    None.
  1374. d169 2
  1375. a170 2
  1376.     int            mountCount;
  1377.     int            maxChildren;
  1378. d184 4
  1379. a187 1
  1380.     for (pass = 0; pass < maxPass; pass++) {
  1381. d195 5
  1382. d210 1
  1383. d213 1
  1384. a222 6
  1385.         if (WIFSIGNALED(waitStatus) || WIFSTOPPED(waitStatus)) {
  1386.             (void) fprintf(stderr,"fscheck did not finish.\n");
  1387.             returnCode = HARDERROR;
  1388.             doneChildren++;
  1389.             continue;
  1390.         }
  1391. d227 1
  1392. d231 18
  1393. a248 5
  1394.         if (waitStatus.w_retcode != FSCHECK_OUT_OF_MEMORY) {
  1395.             mountPtr->doCheck = FALSE;
  1396.             if ((int) waitStatus.w_retcode < 0 ) {
  1397.             PrintFscheckError((int) waitStatus.w_retcode, mountPtr);
  1398.             mountPtr->status = FAILURE;
  1399. d250 2
  1400. a251 2
  1401.             } else if ((int) waitStatus.w_retcode > 0) {
  1402.             PrintFscheckError((int) waitStatus.w_retcode, mountPtr);
  1403. d256 1
  1404. a256 1
  1405.             PrintFscheckError((int) waitStatus.w_retcode, mountPtr);
  1406. a257 1
  1407.             doneChildren++;
  1408. d264 5
  1409. d270 8
  1410. a277 3
  1411.         (void) exit(REBOOT);
  1412.         } else if (returnCode == HARDERROR) {
  1413.         (void) exit(HARDERROR);
  1414. a278 1
  1415.         CacheWriteBack(TRUE);
  1416. d349 5
  1417. a353 5
  1418.     int        pass;
  1419.     int        mountCount;
  1420.     int        maxChildren;
  1421.     ChildInfo    *childInfo;
  1422.     int        *mountIndexPtr;
  1423. d358 2
  1424. a359 1
  1425.     static char    device[MAX_FIELD_LENGTH];
  1426. a361 1
  1427.     static char    deviceName[MAX_FIELD_LENGTH];
  1428. d364 3
  1429. d369 2
  1430. a370 1
  1431.         mountTable[mountIndex].doCheck) {
  1432. d378 3
  1433. a380 1
  1434.     (void) strcpy(device, mountPtr->source);
  1435. a381 1
  1436.     device[strlen(mountPtr->source) - 1] = '\0';
  1437. d383 2
  1438. d387 1
  1439. d392 4
  1440. a395 3
  1441.     (void) sprintf(outputFile, "%s/%s.fsc", outputDir, &(deviceName[i]));
  1442.     StartExec("fscheck");
  1443.     AddExecArgs("-dev", device,NULL);
  1444. d397 1
  1445. d406 1
  1446. a406 1
  1447.     if (mountPtr->root == TRUE) {
  1448. d413 4
  1449. d419 3
  1450. d426 1
  1451. d444 1
  1452. a444 1
  1453.  *    A process is forked to add the prefixes.
  1454. d451 1
  1455. a451 1
  1456.     int        count;
  1457. d457 2
  1458. d461 12
  1459. a472 1
  1460.     if (mountTable[i].status == OK && mountTable[i].root != TRUE) {
  1461. d480 3
  1462. d498 3
  1463. @
  1464.